package org.correct.crawler;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.correct.model.HtmlItem;
import org.correct.util.Counter;
import org.correct.util.Queue;

/**
 * To start the AnalyzeManager, the following steps should be done before
 * the <code>start()</code> method is called:
 * 1. set a <code>CrawlManager</code>.
 * 2. 
 * 
 * @author Li Yujia
 * 
 * @deprecated
 */
public class AnalyzeManager extends Thread {
	private Queue<String> htmlToExtractQueue;
	private Queue<HtmlItem> htmlToStoreQueue;
	private CrawlManager crawlManager;
	private Counter threadCounter;
	private Counter htmlCounter;
	private final int maxStoreThreadNum;
	private String htmlBase;
	
	public AnalyzeManager(String htmlBase) {
		this.threadCounter = new Counter();
		this.htmlCounter = new Counter();
		this.htmlToExtractQueue = new Queue<String>();
		this.htmlToStoreQueue = new Queue<HtmlItem>();
		this.htmlBase = htmlBase;
		this.maxStoreThreadNum = 20;
	}
	
	public AnalyzeManager(String htmlBase, int maxStoreThreadNum) {
		this.threadCounter = new Counter();
		this.htmlCounter = new Counter();
		this.htmlToExtractQueue = new Queue<String>();
		this.htmlToStoreQueue = new Queue<HtmlItem>();
		this.htmlBase = htmlBase;
		this.maxStoreThreadNum = maxStoreThreadNum;
	}
	
	public void setCrawlManager(CrawlManager mgr) {
		this.crawlManager = mgr;
	}
	
	public void addHtml(String html) {
		this.htmlToExtractQueue.add(html);
		this.htmlToStoreQueue.add(new HtmlItem(html));
		notifyAnalyzer();
	}
	
	public void addHtml(String html, String encoding) {
		this.htmlToExtractQueue.add(html);
		this.htmlToStoreQueue.add(new HtmlItem(html, encoding));
		notifyAnalyzer();
	}
	
	public void run() {
		try {
			while(true) {
				while(htmlToExtractQueue.peek() == null && 
						(htmlToStoreQueue.peek() == null ||
						threadCounter.val() >= this.maxStoreThreadNum))
					synchronized(this) {
						wait();
					}
				store();
				extract();
			}
		} catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	private void store() {
		threadCounter.inc();
		final HtmlItem htmlItem = htmlToStoreQueue.poll();
		if(htmlItem == null) {
			threadCounter.dec();
			notifyAnalyzer();
			return;
		}
		new Thread() {
			public void run() {
				int id = htmlCounter.inc();
				System.out.println("Writing file #" + id);
				String fileName = htmlBase + "\\" + id + ".html";
				try {
					PrintWriter w = new PrintWriter(fileName, htmlItem.encoding);
					w.println(htmlItem.html);
					w.flush();
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (Exception e) {
					File f = new File(fileName);
					f.delete();
				}
				
				threadCounter.dec();
				notifyAnalyzer();
			}
		}.start();
	}
	
	private void extract() {
		String html = this.htmlToExtractQueue.peek();
		if(html == null)
			return;
		
		Pattern pattern = Pattern.compile("href ?= ?\"(http://.+?)\"");
		Matcher matcher = pattern.matcher(html);
		
		while(matcher.find()) 
			crawlManager.addUrl(matcher.group(1));
	}
	
	private void notifyAnalyzer() {
		synchronized(this) {
			notify();
		}
	}
}
